#import "View.h"
#import "ViewListener.h"
#import "collaboration_subsystem.h"

@implementation View

@synthesize tipo;

- (id)initWithFrame:(NSRect)frame 
{	
    self = [super initWithFrame:frame];
    if (self) {
		tipo = 1;
		
		lines_array = [[NSMutableArray alloc] init];
		rects_array = [[NSMutableArray alloc] init];
		ovals_array = [[NSMutableArray alloc] init];
		hand_draw_array = [[NSMutableArray alloc] init];
		
		points_array = [[NSMutableArray alloc] init];
		[[NSColorPanel sharedColorPanel] setColor:[NSColor blackColor]];
		
		//////////////////////////////////////////////
		/////// CREACION DEL LISTENING OBJECT   //////
		//////////////////////////////////////////////
		
		obj = new ListeningObject();
		collaboration::EVENT_HANDLER->register_object(obj);
		obj->addEventListener(new LineListener(self));
		obj->addEventListener(new CircleListener(self));
		obj->addEventListener(new RectangleListener(self));
		obj->addEventListener(new HandDrawListener(self));
		obj->addEventListener(new MethodListener(self));
		obj->addEventListener(new TempListener(self));
		
		///////////////////////////////////////////////
    }
    return self;
}

-(void)awakeFromNib
{
}

- (void)drawRect:(NSRect)rect 
{
	NSUInteger i,j,n,n2;
	NSPoint p0, p1;
	NSSize size;
	NSRect rect_aux;
	NSColor* c;
	NSMutableArray* aux_p;
	NSBezierPath* path;
	
	[[NSColor whiteColor] set];
	NSRectFill(rect);
	
	n = [lines_array count];
	for (i=0; i<n; i+=3)
	{
		p0 = [[lines_array objectAtIndex:i] pointValue];
		p1 = [[lines_array objectAtIndex:i+1] pointValue];
		c = [lines_array objectAtIndex:i+2];
		
		[c set];
		[NSBezierPath strokeLineFromPoint:p0 toPoint:p1];
	}
	
	n = [rects_array count];
	for (i=0; i<n; i+=3)
	{
		p0 = [[rects_array objectAtIndex:i] pointValue];
		size = [[rects_array objectAtIndex:i+1] sizeValue];
		c = [rects_array objectAtIndex:i+2];
		rect_aux = NSMakeRect(p0.x, p0.y, size.width, size.height);
		
		[c set];
		[[NSBezierPath bezierPathWithRect:rect_aux] stroke];
	}
	
	n = [ovals_array count];
	for (i=0; i<n; i+=2)
	{
		rect_aux = [[ovals_array objectAtIndex:i] rectValue];
		c = [ovals_array objectAtIndex:i+1];
		
		[c set];
		[[NSBezierPath bezierPathWithOvalInRect:rect_aux] stroke];
	}
	
	n = [hand_draw_array count];
	for (i=0; i<n; i+=2)
	{
		aux_p = [hand_draw_array objectAtIndex:i];
		c = [hand_draw_array objectAtIndex:i+1];
		
		n2 = [aux_p count];
		path = [[NSBezierPath alloc] init];
		
		[c set];
		for (j=0; j<n2; j++)
		{
			p0 = [[aux_p objectAtIndex:j] pointValue];
			[path moveToPoint:p0];
			if (j+1 < n2)
			{
				p0 = [[aux_p objectAtIndex:j+1] pointValue];
				[path lineToPoint:p0];
			}
		}
		
		[path stroke];
		[path dealloc];
	}
}

-(void)dealloc
{
	[points_array dealloc];
	[[NSNotificationCenter defaultCenter] removeObserver:self];
	[super dealloc];
}

-(void)mouseDown:(NSEvent*)theEvent
{
	point_init = [theEvent locationInWindow];
	
	if (tipo == 4)
	{
		[points_array addObject: [NSValue valueWithPoint:point_init]];
	}
}

-(void)rightMouseDown:(NSEvent*)theEvent
{
	tipo = ((tipo+1)%5);
	if (tipo == 0) tipo = 1;
}

-(void)mouseUp:(NSEvent*)theEvent
{
	CGFloat x,y,radius,width,height;
	NSPoint p;
	NSUInteger n,i;
	
	point_end = [theEvent locationInWindow];
	NSColor* color = [[NSColorPanel sharedColorPanel] color];
	
	//////////////////////////////////////////////
	////////////     ENVIO DE EVENTOS    /////////
	//////////////////////////////////////////////
	switch(tipo)
	{
		case 1://envia una linea
			LineEvent* evt = new LineEvent(point_init.x, point_init.y,
										   point_end.x, point_end.y);
			
			evt->color([[color hexadecimalValue] UTF8String]);
			
			collaboration::EVENT_HANDLER->push(evt);
			break;
			
		case 2://envia un rectangulo
			width = point_end.x-point_init.x;
			height = point_end.y-point_init.y;
			
			RectangleEvent* r_evt = new RectangleEvent(point_init.x, point_init.y, 
														width, height);
			
			r_evt->color([[color hexadecimalValue] UTF8String]);
			
			collaboration::EVENT_HANDLER->push(r_evt);
			break;
			
		case 3://envia un circulo
			x = point_end.x-point_init.x;
			y = point_end.y-point_init.y;
			radius = sqrt(x*x+y*y);
			CircleEvent* c_evt = new CircleEvent(point_init.x, point_init.y, radius);
			
			c_evt->color([[color hexadecimalValue] UTF8String]);
			
			collaboration::EVENT_HANDLER->push(c_evt);

			break;
		
		case 4: //envia mano alzada
			n = [points_array count];
			HandDrawEvent* hde = new HandDrawEvent(n);
			for(i=0;i<n;i++)
			{
				p = [[points_array objectAtIndex:i] pointValue];
				hde->xn(i, p.x);
				hde->yn(i, p.y);
			}
			
			hde->color([[color hexadecimalValue] UTF8String]);
			collaboration::EVENT_HANDLER->push(hde);
			
			[points_array removeAllObjects];
			break;
	}
	
	////////////////////////////////////////////////////////////
}

-(void)mouseDragged:(NSEvent*)theEvent
{	
	if (tipo == 4)
	{
		point_end = [theEvent locationInWindow];
		[points_array addObject: [NSValue valueWithPoint: point_end]];
	}
}

-(void) drawLineFromPoint: (NSPoint)p0 toPoint: (NSPoint)p1 withColor: (NSColor*)color
{
	[lines_array addObject:[NSValue valueWithPoint:p0]];
	[lines_array addObject:[NSValue valueWithPoint:p1]];
	[lines_array addObject:color];
	
	[self setNeedsDisplay:YES];
}

-(void) drawRectFromPoint: (NSPoint)p0 withSize: (NSSize)size withColor: (NSColor*)color
{
	[rects_array addObject:[NSValue valueWithPoint:p0]];
	[rects_array addObject:[NSValue valueWithSize:size]];
	[rects_array addObject:color];
	
	[self setNeedsDisplay:YES];
}	

-(void) drawOvalFromPoint: (NSPoint)p0 withRadius: (CGFloat)radius withColor: (NSColor*)color
{
	CGFloat x = p0.x-radius;
	CGFloat y = p0.y-radius;
	NSRect rect = NSMakeRect(x, y, radius*2, radius*2);
	
	[ovals_array addObject:[NSValue valueWithRect:rect]];
	[ovals_array addObject:color];
	
	[self setNeedsDisplay:YES];
}

-(void) drawPoints: (NSMutableArray*)points withColor: (NSColor*)color
{
	[hand_draw_array addObject: points];
	[hand_draw_array addObject: color];
	
	[self setNeedsDisplay:YES];
}

-(void) showPanel: (NSString*)str
{
	[label setStringValue:str];
}

-(void)cleanAll
{	
	[lines_array removeAllObjects];
	[rects_array removeAllObjects];
	[ovals_array removeAllObjects];
	[hand_draw_array removeAllObjects];
	
	[self setNeedsDisplay:YES];
}

- (void)viewDidMoveToWindow
{
	[[NSNotificationCenter defaultCenter] addObserver:self  
											 selector:@selector(windowResized:) name:NSWindowDidResizeNotification  
											   object:[self window]];
}

- (void)windowResized:(NSNotification *)notification;
{
	NSSize size = [[self window] frame].size;
	
	Event* ev = new Event();
	ev->member_value("type", (PortableInteger)METHOD_LISTENER_TYPE);
	ev->member_value("method", "resize");
	ev->member_value("width", (PortableFloat)size.width);
	ev->member_value("height", (PortableFloat)size.height);
	
	collaboration::EVENT_HANDLER->push(ev);
	
	[self setFrameSize:size];
}

-(void)setTemp:(float)afloat
{
	NSColor* c;
	if (afloat >= 0 && afloat <=0.25)
		c = [NSColor cyanColor];
	
	if (afloat >0.25 && afloat <=0.5)
		c = [NSColor blueColor];
	
	if (afloat > 0.5 && afloat <= 0.75)
		c = [NSColor orangeColor];
	
	if (afloat > 0.75 && afloat <= 1)
		c = [NSColor redColor];
	
	[label setBackgroundColor:c];
}

@end


@implementation NSColor(NSColorHexadecimalValue)

-(NSString*)hexadecimalValue
{
	float redFloatValue, greenFloatValue, blueFloatValue;
	int redIntValue, greenIntValue, blueIntValue;
	NSString *redHexValue, *greenHexValue, *blueHexValue;
	
	NSColor *convertedColor=[self colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
	
	if(convertedColor)
	{
		[convertedColor getRed:&redFloatValue green:&greenFloatValue blue:&blueFloatValue alpha:NULL];
		
		redIntValue=redFloatValue*255.99999f;
		greenIntValue=greenFloatValue*255.99999f;
		blueIntValue=blueFloatValue*255.99999f;
		
		redHexValue=[NSString stringWithFormat:@"%02x", redIntValue];
		greenHexValue=[NSString stringWithFormat:@"%02x", greenIntValue];
		blueHexValue=[NSString stringWithFormat:@"%02x", blueIntValue];
		
		return [NSString stringWithFormat:@"0x%@%@%@", redHexValue, greenHexValue, blueHexValue];
	}
	return nil;
}

-(NSString*)htmlHexadecimalValue
{
	float redFloatValue, greenFloatValue, blueFloatValue;
	int redIntValue, greenIntValue, blueIntValue;
	NSString *redHexValue, *greenHexValue, *blueHexValue;
	
	NSColor *convertedColor=[self colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
	
	if(convertedColor)
	{
		[convertedColor getRed:&redFloatValue green:&greenFloatValue blue:&blueFloatValue alpha:NULL];
		
		redIntValue=redFloatValue*255.99999f;
		greenIntValue=greenFloatValue*255.99999f;
		blueIntValue=blueFloatValue*255.99999f;
		
		redHexValue=[NSString stringWithFormat:@"%02x", redIntValue];
		greenHexValue=[NSString stringWithFormat:@"%02x", greenIntValue];
		blueHexValue=[NSString stringWithFormat:@"%02x", blueIntValue];
		
		return [NSString stringWithFormat:@"#%@%@%@", redHexValue, greenHexValue, blueHexValue];
	}
	return nil;
}

+ (NSColor *) colorFromHexRGB:(NSString *) inColorString
{
	NSColor *result = nil;
	unsigned int colorCode = 0;
	unsigned char redByte, greenByte, blueByte;
	
	if (nil != inColorString)
	{
		NSScanner *scanner = [NSScanner scannerWithString:inColorString];
		(void) [scanner scanHexInt:&colorCode];	
	}
	redByte		= (unsigned char) (colorCode >> 16);
	greenByte	= (unsigned char) (colorCode >> 8);
	blueByte	= (unsigned char) (colorCode);	
	result = [NSColor
			  colorWithCalibratedRed:		(float)redByte	/ 0xff
			  green:	(float)greenByte/ 0xff
			  blue:	(float)blueByte	/ 0xff
			  alpha:1.0];
	return result;
}

@end



